package com.dianban.controller.shaliangjie;

import com.alibaba.fastjson.JSONObject;
import com.dianban.base.ResultCode;
import com.dianban.base.ResultVo;
import com.dianban.config.redis.RedisConstant;
import com.dianban.config.redis.RedisUtil;
import com.dianban.controller.BaseController;
import com.dianban.entity.FacePayConfig;
import com.dianban.entity.FacePayStoreOrder;
import com.dianban.entity.User;
import com.dianban.plugin.weixinpay.SljLeshuaPayAppletPlugin;
import com.dianban.plugin.weixinpay.SljWeiXinPayAppletPlugin;
import com.dianban.service.FacePayCommissionLogService;
import com.dianban.service.FacePayConfigService;
import com.dianban.service.FacePayStoreOrderService;
import com.dianban.service.UserService;
import com.dianban.utils.DateUtils;
import com.dianban.utils.HttpsUtil;
import com.dianban.utils.UserUtils;
import com.dianban.utils.XiaomaiguiUtils;
import com.dianban.weixin.util.WechatUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api(value = "ApiSljWechatSmallController", description = "沙粮姐微信小程序认证控制器")
@RequestMapping(value = "${interfacePath}/shaliangjie/wechat/")
public class ApiSljWechatSmallController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(ApiSljWechatSmallController.class);

    @Value("${wechat.shaliangjie.public_weixin_key}")
    private String PUBLIC_WEIXIN_KEY;
    @Value("${wechat.shaliangjie.app_id}")
    private String APPID;
    @Value("${wechat.shaliangjie.secret}")
    private String SECRET;

    @Autowired
    private UserService userService;
    @Autowired
    private FacePayStoreOrderService facePayStoreOrderService;
    @Autowired
    private SljWeiXinPayAppletPlugin weiXinPayAppletPlugin;
    @Autowired
    private FacePayCommissionLogService facePayCommissionLogService;
    @Autowired
    private SljLeshuaPayAppletPlugin leshuaPayAppletPlugin;
    @Autowired
    private FacePayConfigService facePayConfigService;

    @RequestMapping("/jscode2session")
    @ResponseBody
    public ResultVo jscode2session(String code) {
        logger.info("沙粮姐微信小程序登录凭证校验，code:" + code);
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> resultMap = new HashMap<>();
        try {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APPID + "&secret=" + SECRET + "&js_code=" + code + "&grant_type=authorization_code";
            String result = HttpsUtil.callHttps("", url);
            if (StringUtils.isNotBlank(result)) {
                JSONObject jsonObject = JSONObject.parseObject(result);
                if (jsonObject != null) {
                    resultMap.put("openid", StringUtils.isEmpty((String) jsonObject.get("openid")) ? "" : jsonObject.get("openid"));
                    resultMap.put("session_key", StringUtils.isEmpty((String) jsonObject.get("session_key")) ? "" : jsonObject.get("session_key"));
                } else {
                    resultMap.put("openid", "");
                    resultMap.put("session_key", "");
                }
            }
            logger.info("沙粮姐微信小程序登录凭证校验返回：{}", result);
        } catch (Throwable e) {
            logger.error("沙粮姐微信小程序登录凭证校验接口异常," + e.toString());
            map.put("result", false);
            map.put("data", resultMap);
            map.put("errorMsg", "系统异常，请稍后重试或联系管理员！");
            return ResultVo.error(ResultCode.ERROR, "系统异常，请稍后重试或联系管理员！");
        }
        map.put("result", true);
        map.put("data", resultMap);
        map.put("errorMsg", "");
        return ResultVo.success(resultMap, "获取成功");
    }

    // 绑定用户的openid以及是否开通了免密支付的签约
    // https://www.jianshu.com/p/3bb8b74ceedf
    @RequestMapping(value = "/bindOpenid", method = RequestMethod.GET)
    @ApiOperation(value = "沙粮姐微信小程序用户绑定openid")
    @ResponseBody
    public ResultVo bindOpenid(String openid, HttpServletRequest request, HttpServletResponse response) {
        logger.error("沙粮姐微信小程序用户绑定openid，openid:{}", openid);
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> resultMap = new HashMap<>();
        try {
            String userToken = request.getHeader(UserUtils.USER_TOKEN);
            String key = RedisConstant.USER_TOKEN_KEY + userToken;
            User user = (User) RedisUtil.get(key);
            if (user == null) {
                return ResultVo.error(ResultCode.ERROR, "请求头userToken过期");
            }
            User _user = userService.findById(Long.valueOf(user.getId()));
            if (_user != null && StringUtils.isNotBlank(_user.getOpenid())) {
                resultMap.put("user", _user);
                map.put("result", true);
                map.put("data", resultMap);
                map.put("errorMsg", "");
                return ResultVo.success(resultMap, "获取成功");
            }
            _user.setOpenid(openid);
            userService.updateOpenid(openid, String.valueOf(user.getId()));
            resultMap.put("user", _user);
        } catch (Throwable e) {
            logger.error("沙粮姐微信小程序用户绑定openid," + e.toString());
            map.put("result", false);
            map.put("data", resultMap);
            map.put("errorMsg", "系统异常，请稍后重试或联系管理员！");
            return ResultVo.error(ResultCode.ERROR, "系统异常，请稍后重试或联系管理员！");
        }
        map.put("result", true);
        map.put("data", resultMap);
        map.put("errorMsg", "");
        return ResultVo.success(resultMap, "获取成功");
    }

    @ApiOperation(notes = "micropay", httpMethod = "POST", value = "进行发起订单支付")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userToken", value = "用户token", required = true, paramType = "header", dataType = "string"),
            @ApiImplicitParam(name = "openid", value = "openid", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "micropay", method = RequestMethod.POST)
    public ResultVo micropay(String openid, String orderNumber, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isBlank(openid)) {
            return ResultVo.error(ResultCode.ERROR, "openid不能为空");
        }
        if (StringUtils.isBlank(orderNumber)) {
            return ResultVo.error(ResultCode.ERROR, "订单号不能为空");
        }
        FacePayStoreOrder facePayStoreOrder = facePayStoreOrderService.findByOrderNumber(orderNumber);
        if (facePayStoreOrder == null) {
            return ResultVo.error(ResultCode.ERROR, "订单号错误");
        }
        String sn = facePayStoreOrderService.buildOrderNumber("SLJ");

//        Object objRedis = RedisUtil.get("payOrderNumber-" + sn);
//        if (objRedis != null) {
//            return ResultVo.error(ResultCode.ERROR, "正在支付中");
//        }
        boolean hasOrderNumber = RedisUtil.hasKey(orderNumber);
        if (hasOrderNumber) {
            return ResultVo.error(ResultCode.ERROR, "支付中，请稍等");
        } else {
            RedisUtil.set(orderNumber, 1, 30);
        }

        BigDecimal money = facePayStoreOrder.getMoney();
        FacePayStoreOrder facePayStoreOrderUpdate = new FacePayStoreOrder();
        facePayStoreOrderUpdate.setOrderNumber(orderNumber);
        facePayStoreOrderUpdate.setPayNumber(sn);
        facePayStoreOrderService.updateSlj(facePayStoreOrderUpdate);
        List<FacePayConfig> facePayConfigList = facePayConfigService.find(30, 1, null);
        if (facePayConfigList != null && !facePayConfigList.isEmpty() && "1".equals(facePayConfigList.get(0).getValue())) {
            //RedisUtil.set("payOrderNumber-" + sn, sn, 30);
            try {
                facePayStoreOrderService.updatePayTypeAndChannel(facePayStoreOrder.getId(), "乐刷-微信小程序-支付");
            } catch (Throwable e) {
            }
            return leshuaPayAppletPlugin.getParameterMap(sn, facePayStoreOrder.getMemo(), facePayStoreOrder.getMemo(), money, openid, request);
        } else {
            //RedisUtil.set("payOrderNumber-" + sn, sn, 30);
            try {
                facePayStoreOrderService.updatePayTypeAndChannel(facePayStoreOrder.getId(), "微信-微信小程序-支付");
            } catch (Throwable e) {
            }
            Map<String, Object> params = weiXinPayAppletPlugin.getParameterMap(sn, facePayStoreOrder.getMemo(), facePayStoreOrder.getMemo(), money, openid, request);
            logger.info("micropay : {}", JSONObject.toJSONString(params));
            return ResultVo.success(params, "成功");
        }
    }

    @RequestMapping(value = "asyncNotify/{sn}")
    public String asyncNotify(@PathVariable String sn, HttpServletRequest request) {
        String result = "";
        try {
            if (StringUtils.isBlank(sn)) {
                return result;
            }
            FacePayStoreOrder facePayStoreOrder = facePayStoreOrderService.findByPayNumber(sn);
            if (facePayStoreOrder == null) {
                return result;
            }
            if (20 == facePayStoreOrder.getPayStatus()) {
                return weiXinPayAppletPlugin.getNotifyMessage();
            }
            String tradeSn = weiXinPayAppletPlugin.verifyNotify(sn, facePayStoreOrder.getMoney(), request);
            if (StringUtils.isNotBlank(tradeSn)) {
                int count = facePayStoreOrderService.updateStateAndCommission(facePayStoreOrder);
                if (count == 1) {
                    // 支付成功推送订阅消息
                    try {
                        if (facePayStoreOrder != null) {
                            User user = userService.findById(facePayStoreOrder.getUserId());
                            String payTime = facePayStoreOrder.getUpdatetime() != null ? DateUtils.format(new Date(facePayStoreOrder.getUpdatetime() * 1000), DateUtils.Y_M_D_H_M_S) : DateUtils.formatNow(DateUtils.Y_M_D_H_M_S);
                            if (user != null && StringUtils.isNotBlank(user.getOpenid())) {
                                WechatUtils.pay_success(user.getOpenid(), facePayStoreOrder.getOrderNumber(), payTime, String.valueOf(facePayStoreOrder.getMoney()));
                            }
                            // 推送订单支付成功通知给小卖柜
                            List<FacePayConfig> facePayConfigList = facePayConfigService.find(110, 1, facePayStoreOrder.getStoreId());
                            for (FacePayConfig facePayConfig : facePayConfigList) {
                                String name = facePayConfig.getName();
                                XiaomaiguiUtils.orderNotify(name, facePayStoreOrder.getOrderNumber(), facePayStoreOrder.getPayNumber(), facePayStoreOrder.getMoney(), payTime);
                            }
                        }
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                    return weiXinPayAppletPlugin.getNotifyMessage();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return result;
        }
        return result;
    }

    @RequestMapping(value = "leshua/asyncNotify/{sn}")
    public String leshuaAsyncNotify(@PathVariable String sn, HttpServletRequest request) {
        String result = "";
        try {
            if (StringUtils.isBlank(sn)) {
                return result;
            }
            FacePayStoreOrder facePayStoreOrder = facePayStoreOrderService.findByPayNumber(sn);
            if (facePayStoreOrder == null) {
                return result;
            }
            if (20 == facePayStoreOrder.getPayStatus()) {
                return leshuaPayAppletPlugin.getNotifyMessage();
            }
            String tradeSn = leshuaPayAppletPlugin.verifyNotify(sn, facePayStoreOrder.getMoney(), request);
            if (StringUtils.isNotBlank(tradeSn)) {
                int count = facePayStoreOrderService.updateStateAndCommission(facePayStoreOrder);
                if (count == 1) {
                    // 支付成功推送订阅消息
                    try {
                        if (facePayStoreOrder != null) {
                            User user = userService.findById(facePayStoreOrder.getUserId());
                            String payTime = facePayStoreOrder.getUpdatetime() != null ? DateUtils.format(new Date(facePayStoreOrder.getUpdatetime() * 1000), DateUtils.Y_M_D_H_M_S) : DateUtils.formatNow(DateUtils.Y_M_D_H_M_S);
                            if (user != null && StringUtils.isNotBlank(user.getOpenid())) {
                                WechatUtils.pay_success(user.getOpenid(), facePayStoreOrder.getOrderNumber(), payTime, String.valueOf(facePayStoreOrder.getMoney()));
                            }
                            // 推送订单支付成功通知给小卖柜
                            List<FacePayConfig> facePayConfigList = facePayConfigService.find(110, 1, facePayStoreOrder.getStoreId());
                            for (FacePayConfig facePayConfig : facePayConfigList) {
                                String name = facePayConfig.getName();
                                XiaomaiguiUtils.orderNotify(name, facePayStoreOrder.getOrderNumber(), facePayStoreOrder.getPayNumber(), facePayStoreOrder.getMoney(), payTime);
                            }
                        }
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                    return leshuaPayAppletPlugin.getNotifyMessage();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return result;
        }
        return result;
    }

}
